昨天已經新增了子頁面,之前是直接將照片嵌入在網頁中,並沒有考慮到店家與照片的關聯,今天要在子頁面上面放上對應店家的圖片。

更新 Photo ORM
一間店會有很多照片,因此我們需要將 Place 跟 Photo 建立一對多的關係。
在Django ORM的設計中,可以在一個物件中嵌入 Foreign Key 建立一對多的關係。
程式碼
# food/model.py
class Photo(models.Model):
    name = models.CharField(max_length=255)
    file = models.ImageField(upload_to='photos')
    place = models.ForeignKey(Place, help_text="The place that this photo come from.", on_delete=models.SET_NULL, null=True)
Q:餐廳若是關起來了,我上傳的照片會怎麼樣?
A:兩個資料有關聯時,其中一筆資料(舉例餐廳)被刪除時常見有兩種做法。
中間有一個參數 on_delete=models.SET_NULL 就是表示 Place 被刪除時,不會刪除此Photo,只會設定為Null
https://www.delftstack.com/zh-tw/howto/django/django-setup-one-to-many-relationship/
https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/
修改完一樣要記得 makemigrations 和 migrate
python manage.py makemigrations
python manage.py migrate
將此店家的所有照片傳至模板
有兩種方法可以達成這個任務
直接在Photo 資料表中,找出屬於這一間餐廳的照片,使用filter() 這個過濾器,裡面可以直接使用place這個參數 。
photo_list = Photo.objects.filter(place = place).all()
從餐廳的角度去搜尋,找出這間餐廳的所有照片,
因為Place 和 Photo 有關係,因此Django會自動幫Place產生photo_set這個變數,代表的就是這家餐廳的所有照片。
place.photo_set.all()
兩者的結果是一致的,只是思考思路和語法有所不同。
def place_introduction(request, place_id: int):
    place = Place.objects.get(id=place_id)
    # 方法一
    # photo_list = Photo.objects.filter(place = place).all()
    # 方法二
    photo_list = place.photo_set.all()
    return render(
        request,
        'food/place_introduction.html',
        {'store': place,
         'photo_list':photo_list,
         },
    )
integrate data
最後我們執行runserver進入/admin,將照片上傳到資料庫
會發現在place的地方成為了選單,內容是之前新增的店家資料


台南不需要米其林
- 專案程式碼
- 專案文件與鐵人賽文章
- 參賽團隊 台南巷弄美食獵人